/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package biofilter.filters;

import biofilter.exceptions.InvalidRecordException;
import biofilter.records.Record;
import biofilter.sources.RecordsFile;

/**
 * This is a split filter with a very specific roll.  Usually a split filter
 * requires slurping in the entire file into memory, splitting the file into records
 * and then each time getRecord() is called, returning the next record.
 *
 * This filter differs.  It is required to keep a low memory footprint as it streams
 * data into records.  So the behavior is as follows:
 * 1) if this filter has additional records (in the file) then return the next record in the file
 * 2) if this filter does not have additional records, then go to your source.  Get the next record.
 * Open this record and then start streaming data from it.
 * @author Daniel Quest
 * @date   April 13 2010
 */
public class SplitFileNoMemoryFilterBase extends RecordsFilter  {

    @Override
    protected Record transformRecord(Record r) throws InvalidRecordException {
        throw new UnsupportedOperationException("SplitFileNoMemoryFilterBase: Transform Record Not supported .");
    }

    /**
     * To indicate whether all records have been processed and returned by this filter.
     * @return boolean - true if all records have been processed, false if not
     */
    @Override
    public boolean eof() {
        if(singleLineRecords == null){
            return source.eof();
        }else {
            if (source.eof() && singleLineRecords.eof()) return true;
            else return false;
        }
    }

    /**
     * To get the original record, maintain the original records and transfomred
     * records lists, and to call transformRecord to transform the record
     * @return Record - the transformed record
     */
    RecordsFile singleLineRecords = null;
    @Override
    public Record getRecord() throws InvalidRecordException {
        this.transformedRecord = null;
        if (!(this.source instanceof RecordsFile)){
            throw new InvalidRecordException("Source to the RecordsFile2BowtieRecord filter must be a RecordsFile");
        }
        if (this.source == null){
            throw new InvalidRecordException("Source to RecordsFile2BowtieRecord filter can not be null!");
        }

        //if we are currently at the end of a set of records to process, e.g. the end of a file
        //or we don't currently have a set of records to process
        //then setup the RecordsFile
        if ( (singleLineRecords == null || singleLineRecords.eof() ) && !this.source.eof() ){
            String filename = this.source.getRecord().get(); //get the next filename
            singleLineRecords = new RecordsFile(filename, "biofilter.records.FileNameRecord");
        }

        if ( !singleLineRecords.eof() ){
            this.originalRecord = singleLineRecords.getRecord();
            if ( this.originalRecord != null) {
                this.transformedRecord = this.transformRecord( this.originalRecord );
            }
        }

        return this.transformedRecord;
    }

    public Record peek() throws InvalidRecordException {
        throw new UnsupportedOperationException("Not supported yet.");
    }

}
